package storage;

import java.awt.BorderLayout;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
import java.util.Vector;

import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;

import control.BudgetManager;
import control.CategoryManager;
import control.ExpenseManager;
import control.IncomeManager;
import control.LoanManager;
import control.MemberManager;
import control.PaymentMethodManager;
import control.Shell;

//@author A0098891H
public class ManageData {
	private static final String dir = System.getProperty("user.dir");
	private static final String dataFolder = "/data/";
	private static final String confFolder = "/conf/";
	
	/**
	 * 
	 * @param xpnManager
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static boolean saveExpenseManagerToFile(ExpenseManager xpnManager)
	{  
		Gson gson = new Gson();
		try {
			File file = new File(dir + dataFolder +"xpnManager"+".txt");
			BufferedWriter out = new BufferedWriter(new FileWriter(file));
			out.write(gson.toJson(xpnManager));
			out.flush();
			out.close();
			
		}
		catch(FileNotFoundException fnfe)
		{
			boolean success = (new File(dir + dataFolder)).mkdirs();
			if (!success) {
				System.out.println(dir + dataFolder + " directory creation failed");
				return false;
			}
			System.out.println(dir + dataFolder + " directory created");
			return true;
		}
		catch (IOException ioE) {
			System.out.println("IOEXP");
			return false;
		}		
		return true;
	}
	
    /**
     * 
     * @return
     * @Precondition 
     * @Postcondition 
     */
    public static ExpenseManager loadExpenseManagerFromFile() {
		Gson gson = new Gson();
		ExpenseManager xpnManager = null;
		
        try {
            File file = new File(dir + dataFolder +"xpnManager"+".txt");
            BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
            xpnManager = gson.fromJson(bufferedReader, ExpenseManager.class);
        }
        catch (FileNotFoundException e) {
			System.out.println(dir + dataFolder +"xpnManager.txt not found.");
        }
        catch (JsonSyntaxException jse)
        {
        	System.out.println(dir + dataFolder +"xpnManager.txt corrupted\n");
        	cleanAllData();
        }
        
        return xpnManager;
    }
	/**
	 * 
	 * @param catManager
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static boolean saveCategoryManagerToFile(CategoryManager catManager)
	{  

		Gson gson = new Gson();
		try {
			File file = new File(dir + dataFolder +"catManager"+".txt");
			BufferedWriter out = new BufferedWriter(new FileWriter(file));
			out.write(gson.toJson(catManager));
			out.flush();
			out.close();
		}
		catch(FileNotFoundException fnfe)
		{
			boolean success = (new File(dir + dataFolder)).mkdirs();
			if (!success) {
				System.out.println(dir + dataFolder + " directory creation failed");
				return false;
			}
			System.out.println(dir + dataFolder + " directory created");
			return true;
		}
		catch (IOException ioE) {
			System.out.println("IOEXP");
			return false;
		}		
		return true;
	}
    /**
     * 
     * @return
     * @Precondition 
     * @Postcondition 
     */
    public static CategoryManager loadCategoryManagerFromFile() {
		Gson gson = new Gson();
		CategoryManager catManager = null;
		
        try {
            File file = new File(dir + dataFolder +"catManager"+".txt");
            BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
            catManager = gson.fromJson(bufferedReader, CategoryManager.class);
        }
        catch (FileNotFoundException e) {
			System.out.println(dir + dataFolder +"catManager.txt not found.");
        }
        catch (JsonSyntaxException jse)
        {
        	System.out.println(dir + dataFolder +"catManager.txt corrupted\n");
        	cleanAllData();
        }
        
        return catManager;
    }
	/**
	 * 
	 * @param payManager
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static boolean savePaymentManagerToFile(PaymentMethodManager payManager)
	{  

		Gson gson = new Gson();
		try {
			File file = new File(dir + dataFolder +"payManager"+".txt");
			BufferedWriter out = new BufferedWriter(new FileWriter(file));
			out.write(gson.toJson(payManager));
			out.flush();
			out.close();
		}
		catch(FileNotFoundException fnfe)
		{
			boolean success = (new File(dir + dataFolder)).mkdirs();
			if (!success) {
				System.out.println(dir + dataFolder + " directory creation failed");
				return false;
			}
			System.out.println(dir + dataFolder + " directory created");
			return true;
		}
		catch (IOException ioE) {
			System.out.println("IOEXP");
			return false;
		}		
		return true;
	}
    /**
     * 
     * @return
     * @Precondition 
     * @Postcondition 
     */
    public static PaymentMethodManager loadPaymentManagerFromFile() {
		Gson gson = new Gson();
		PaymentMethodManager payManager = null;
		
        try {
            File file = new File(dir + dataFolder +"payManager"+".txt");
            BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
            payManager = gson.fromJson(bufferedReader, PaymentMethodManager.class);
        }
        catch (FileNotFoundException e) {
			System.out.println(dir + dataFolder +"payManager.txt not found.");
        }
        catch (JsonSyntaxException jse)
        {
        	System.out.println(dir + dataFolder +"payManager.txt corrupted\n");
        	cleanAllData();
        }
        
        return payManager;
    }
    
	/**
	 * 
	 * @param xpnManager
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static boolean saveMemberManagerToFile(MemberManager xpnManager)
	{  

		Gson gson = new Gson();
		try {
			File file = new File(dir + dataFolder +"memManager"+".txt");
			BufferedWriter out = new BufferedWriter(new FileWriter(file));
			out.write(gson.toJson(xpnManager));
			out.flush();
			out.close();
		}
		catch(FileNotFoundException fnfe)
		{
			boolean success = (new File(dir + dataFolder)).mkdirs();
			if (!success) {
				System.out.println(dir + dataFolder + " directory creation failed");
				return false;
			}
			System.out.println(dir + dataFolder + " directory created");
			return true;
		}
		catch (IOException ioE) {
			System.out.println("IOEXP");
			return false;
		}		
		return true;
	}
	
    /**
     * 
     * @return
     * @Precondition 
     * @Postcondition 
     */
    public static MemberManager loadMemberManagerFromFile() {
		Gson gson = new Gson();
		MemberManager memManager = null;
		
        try {
            File file = new File(dir + dataFolder +"memManager"+".txt");
            BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
            memManager = gson.fromJson(bufferedReader, MemberManager.class);
        }
        catch (FileNotFoundException e) {
			System.out.println(dir + dataFolder +"memManager.txt not found.");
        }
        catch (JsonSyntaxException jse)
        {
        	System.out.println(dir + dataFolder +"memManager.txt corrupted\n");
        	cleanAllData();
        }
		 
        return memManager;
    }
    
	/**
	 * 
	 * @param budgetManager
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static boolean saveBudgetManagerToFile(BudgetManager budgetManager)
	{  

		Gson gson = new Gson();
		try {
			File file = new File(dir + dataFolder +"budgetManager"+".txt");
			BufferedWriter out = new BufferedWriter(new FileWriter(file));
			out.write(gson.toJson(budgetManager));
			out.flush();
			out.close();
		}
		catch(FileNotFoundException fnfe)
		{
			boolean success = (new File(dir + dataFolder)).mkdirs();
			if (!success) {
				System.out.println(dir + dataFolder + " directory creation failed");
				return false;
			}
			System.out.println(dir + dataFolder + " directory created");
			return true;
		}
		catch (IOException ioE) {
			System.out.println("IOEXP");
			return false;
		}		
		return true;
	}
    /**
     * 
     * @return
     * @Precondition 
     * @Postcondition 
     */
    public static BudgetManager loadBudgetFromFile() {
		Gson gson = new Gson();
		BudgetManager budgetManager = null;
        try {
            File file = new File(dir + dataFolder +"budgetManager"+".txt");
            BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
            budgetManager = gson.fromJson(bufferedReader, BudgetManager.class);
        }
        catch (FileNotFoundException e) {
			System.out.println(dir + dataFolder +"budgetManager.txt not found.");
        }
        catch (JsonSyntaxException jse)
        { 
        	System.out.println(dir + dataFolder +"budgetManager.txt corrupted\n");
        	cleanAllData();
        }
        return budgetManager;
    }
    
	/**
	 * 
	 * @param incomeManager
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static boolean saveIncomeManagerToFile(IncomeManager incomeManager)
	{  

		Gson gson = new Gson();
		try {
			File file = new File(dir + dataFolder +"incomeManager"+".txt");
			BufferedWriter out = new BufferedWriter(new FileWriter(file));
			out.write(gson.toJson(incomeManager));
			out.flush();
			out.close();
		}
		catch(FileNotFoundException fnfe)
		{
			boolean success = (new File(dir + dataFolder)).mkdirs();
			if (!success) {
				System.out.println(dir + dataFolder + " directory creation failed");
				return false;
			}
			System.out.println(dir + dataFolder + " directory created");
			return true;
		}
		catch (IOException ioE) {
			System.out.println("IOEXP");
			return false;
		}			
		return true;
	}
	
    /**
     * 
     * @return
     * @Precondition 
     * @Postcondition 
     */
    public static IncomeManager loadIncomeManagerFromFile() {
		Gson gson = new Gson();
		IncomeManager incomeManager = null;
		
        try {
            File file = new File(dir + dataFolder +"incomeManager"+".txt");
            BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
            incomeManager = gson.fromJson(bufferedReader, IncomeManager.class);
        }
        catch (FileNotFoundException e) {
			System.out.println(dir + dataFolder +"incomeManager.txt not found.");
        }
        catch (JsonSyntaxException jse)
        {
        	System.out.println(dir + dataFolder +"incomeManager.txt corrupted\n");
        	cleanAllData();
        }
        
        return incomeManager;
    }
    
	/**
	 * 
	 * @param loanManager
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static boolean saveLoanManagerToFile(LoanManager loanManager)
	{  

		Gson gson = new Gson();
		try {
			File file = new File(dir + dataFolder +"loanManager"+".txt");
			BufferedWriter out = new BufferedWriter(new FileWriter(file));
			out.write(gson.toJson(loanManager));
			out.flush();
			out.close();
		}
		catch(FileNotFoundException fnfe)
		{
			boolean success = (new File(dir + dataFolder)).mkdirs();
			if (!success) {
				System.out.println(dir + dataFolder + " directory creation failed");
				return false;
			}
			System.out.println(dir + dataFolder + " directory created");
			return true;
		}
		catch (IOException ioE) {
			System.out.println("IOEXP");
			return false;
		}			
		return true;
	}
	
    /**
     * 
     * @return
     * @Precondition 
     * @Postcondition 
     */
    public static LoanManager loadLoanManagerFromFile() {
		Gson gson = new Gson();
		LoanManager loanManager = null;
		
        try {
            File file = new File(dir + dataFolder +"loanManager"+".txt");
            BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
            loanManager = gson.fromJson(bufferedReader, LoanManager.class);
        }
        catch (FileNotFoundException e) {
			System.out.println(dir + dataFolder +"loanManager.txt not found.");
        }
        catch (JsonSyntaxException jse)
        {
        	System.out.println(dir + dataFolder +"loanManager.txt corrupted\n");
        	cleanAllData();
        }
        return loanManager;
    }
    
	/**
	 * 
	 * @param shell
	 * @return
	 * @Precondition 
	 * @Postcondition 
	 */
	public static boolean saveShellToFile(Shell shell)
	{  

		Gson gson = new Gson();
		try {
			File file = new File(dir + dataFolder +"shell"+".txt");
			BufferedWriter out = new BufferedWriter(new FileWriter(file));
			out.write(gson.toJson(shell));
			out.flush();
			out.close();
		}
		catch(FileNotFoundException fnfe)
		{
			boolean success = (new File(dir + dataFolder)).mkdirs();
			if (!success) {
				System.out.println(dir + dataFolder + " directory creation failed");
				return false;
			}
			System.out.println(dir + dataFolder + " directory created");
			return true;
		}
		catch (IOException ioE) {
			System.out.println("IOEXP");
			return false;
		}			
		return true;
	}
	
    /**
     * 
     * @return
     * @Precondition 
     * @Postcondition 
     */
    public static Shell loadShellFromFile() {
		Gson gson = new Gson();
		Shell shell = null;
		
        try {
            File file = new File(dir + dataFolder +"shell"+".txt");
            BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
            shell = gson.fromJson(bufferedReader, Shell.class);
        }
        catch (FileNotFoundException e) {
			System.out.println(dir + dataFolder +"shell.txt not found.");
        }
        catch (JsonSyntaxException jse)
        {
        	System.out.println(dir + dataFolder +"shell.txt corrupted\n");
        	cleanAllData();
        }
        return shell;
    }
    
    public static void cleanAllData()
    {
    	try
    	{
    	File[] file = new File[8];

        file[0] = new File(dir + dataFolder +"xpnManager"+".txt");
        file[1] = new File(dir + dataFolder +"catManager"+".txt");
        file[2] = new File(dir + dataFolder +"incomeManager"+".txt");
        file[3] = new File(dir + dataFolder +"loanManager"+".txt");
        file[4] = new File(dir + dataFolder +"memManager"+".txt");
        file[5] = new File(dir + dataFolder +"payManager"+".txt");
        file[6] = new File(dir + dataFolder +"budgetManager"+".txt");
        file[7] = new File(dir + dataFolder +"shell"+".txt");
        
        for(int i=0;i<8;i++)
        {
        	if(file[i]!=null)
        	{
        		file[i].delete();
        	}
        }
    	}
    	catch(Exception e)
    	{
    		System.out.println("clean file failed");
    	}
    	
    }
    
    public static boolean loanInvestmentData(Vector<String> name, Vector<Double> ir)
    {
		try {
			File input = new File(dir + confFolder+"investment plans.txt");
			BufferedReader br = new BufferedReader(new FileReader(input));
			@SuppressWarnings("resource")
			Scanner scan = new Scanner(br);
			
			while(scan.hasNext())
			{
				String strItem = scan.nextLine();
				String item[] = strItem.split(",");
				name.add(item[0]);
				ir.add(Double.parseDouble(item[1]));
			}			
		} catch (IOException e) {
			name.clear();
			ir.clear();
			ir.add(0.0);
			ir.add(0.5);
			ir.add(3.0);
			ir.add(8.0);
			name.add("");
			name.add("DBS SAVING PLUS");
			name.add("US SAVINGS SECURITIES");
			name.add("US DOMESTIC SERIES");
			System.out.println(dir + confFolder+"investment plans.txt" + " not found. Dummy Data created");
			return false;
		}		
    	
		return true;
    }

}
